﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//冒泡排序
//void bubble_sort(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz - 1; i++)//一趟循环数组个数减1次
//	{
//		for (int j = 0; j < sz - 1 - i; j++)//一趟中循环的对数
//		{
//			if (arr[j] > arr[j + 1])
//			{
//				int tmp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = arr[j];
//			}
//		}
//
//	}
//
//	return 0;
//}
//
//void print_arr(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", arr);
//	}
//	printf("\n");
//}
//
//int main()
//{
//	int arr[10] = { 3,1,9,8,5,4,0,2,7,6 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	print_arr(arr, sz);
//	void bubble_sort(arr, sz);
//}

//指针第5个视频
//怎么才能让函数排序任意类型的数据？
//1.并不是所有的数据都能使用大小于符合（> <）比较大小；结构体变量，字符串不能直接使用> <比较
//2.交换两个变量的时候中间变量到底应该创建成什么类型
// 3.参数方面也有问题
//
// 使用qsort函数可以实现以上问题
// qsort函数的实现者是微软；使用者是程序员
// 使用者可以排序整型数组，提供一个函数，能实现两个整型元素的比较
// 还可以排序结构体数组，提供一个函数；能够比较两个结构体变量的大小
// 
//void qsort(void* base,//base中存放的是待排序数组的第一个元素地址
//           size_t num,//num存放的是base指向的数组中的元素个数
//           size_t size,//size是base指向的数组中一个元素的长度，单位是字节
//           int (*compare)(const void*e1,const void*e2)//函数指针-指向一个比较函数，这个比较函数是用来比较数组中的两个元素的
//           //如果e1指向的元素大于e2指向的元素，那么函数返回>0的数字
//           //如果e1指向的元素等于e2指向的元素，那么函数返回=0的数字
//           //如果e1指向的元素小于e2指向的元素，那么函数返回<0的数字
// 

//void* 类型的指针不能解引用操作符，也不能+/-整数的操作
//这种指针变量一般是用来存放地址的
//使用之前要强制类型转换成想要的类型

//test1
//void cmp_int(const void* e1,const void*e2)
//{
//	//if (*(int*)e1 > *(int*)e2)//对其进行强制性转换成整形
//	//	return 1;
//	//else if (*(int*)e1 < *(int*)e2)
//	//	return -1;
//	//else
//	//	return 0;
//	//简单写法
//	return *(int*)e1 - *(int*)e2;
//}
//
//void print_arr(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//}
//
//void test1()
//{
//	int arr[] = { 3,1,9,8,5,4,0,2,7,6 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	//利用qsort函数对其进行升序
//	qsort(arr, sz, sizeof(arr[0]), cmp_int);
//	//对其进行打印
//	print_arr(arr,sz);
//}

//test2
//struct Stu
//{
//	char name[50];
//	int age;
//};

//int cmp_stu_by_age(const void* e1, const void* e2)//age
//{
//	return (*(struct Stu*)e1).age - (*(struct Stu*)e2).age;//*解引用
//}

//按照名字来比较大小的时候
//名字是字符串，不能直接使用>比较
//应该使用strcmp函数比较大小
//strcmp(字符1, 字符串2)
//如果字符串1 大于 字符串2，返回 >0的数字
//如果字符串1 等于 字符串2，返回0
//如果字符串1 小于 字符串2，返回 <0的数字

//int cmp_stu_by_name(const void* e1, const void* e2)//name
//{
//	return strcmp((*(struct Stu*)e1).name , (*(struct Stu*)e2).name);
//}
//
//测试qsort函数来排序结构体数组
//void test2()
//{
//	struct Stu s[3] = { {"zhangsan",18},{"lisi",28},{"wangwu",20}};
//	int sz = sizeof(s) / sizeof(s[0]);
//	/*qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);*/
//
//}
//
//int main()
//{
//	/*test1();*/
//	test2();
//	return 0;
//}

//对冒泡排序进行改进

//int int_cmp(const void* p1, const void* p2)
//{
//	return (*(int*)p1 - *(int*)p2);
//}
//
//void _swap(void* p1, void* p2, size_t size)//写一个函数对其进行转换
//{
//	char* ptr1 = (char*)p1;
//	char* ptr2 = (char*)p2;
//	while (size--)
//	{
//		char tmp = *ptr1;
//		*ptr1 = *ptr2;
//		*ptr2 = tmp;
//		ptr1++;
//		ptr2++;
//	}
//}
//
//void bubble_size(void* base, int count, size_t size, int* cmp(const void*, const void*))
//{
//	char* arr = (char*)base;
//	for (int i = 0; i < count - 1; i++)
//	{
//		for (int j = 0; j < count - 1 - i; j++)
//		{
//			if (cmp(arr + j * size, arr + (j + 1) * size) > 0)
//			{
//				_swap(arr + j * size, arr + (j + 1) * size, size);
//			}
//		}
//	}
//}
//
//int main()
//{
//	int arr[10] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	bubble_size(arr, sz, sizeof(int), int_cmp);
//	for (int i = 0; i < sz; i++)
//	{ 
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//	return 0;
//}


//int int_cmp(const void* p1, const void* p2)
//{
//	return (*(int*)p1 - *(int*)p2);
//}
//void _swap(void* p1, void* p2, int size)
//{
//	int i = 0;
//	for (i = 0; i < size; i++)
//	{
//		char tmp = *((char*)p1 + i);
//		*((char*)p1 + i) = *((char*)p2 + i);
//		*((char*)p2 + i) = tmp;
//	}
//}
//void bubble(void* base, int count, int size, int(*cmp)(void*, void*))
//{
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < count - 1; i++)
//	{
//		for (j = 0; j < count - i - 1; j++)
//		{
//			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
//			{
//				_swap((char*)base + j * size, (char*)base + (j + 1) * size,
//					size);
//			}
//		}
//	}
//}
//
//int main()
//{
//	int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
//	int i = 0;
//	bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
//	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
//	{
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//	return 0;
//}
//

//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	printf("%d\n", sz);
//	return 0;
//}


//生命周期
//int a = 10;
//void test()
//{
//	printf("3.a=%d\n", a);
//}
//int main()
//{
//	{
//		printf("1.a=%d\n", a);
//	}
//	printf("2.a=%d\n", a);
//	test();
//	return 0;
//}

//int a = 5;
//static
//void test()
//{
//	static int a = 5;
//	a++;
//	printf("%d ", a);
//}
//int main()
//{
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		test();
//	}
//		
//	return 0;
//}

////extern声明外部符号
//extern int g_val;
//
//int main()
//{
//	printf("%d\n", g_val);
//
//	return 0;
//}


////声明外部函数
//extern int Add(int x, int y);
//
//int main()
//{
//	int a = 10;
//	int b = 20;
//	int c = Add(a, b);
//	printf("%d\n", c);
//
//	return 0;
//}

//调试的视频
//int main()
//{
//	int i = 0;
//	int arr[10] = { 0 };
//
//	for (i = 0; i < 10; i++)
//	{
//		arr[i] = 10 - i;
//	}
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//	return 0;
//

//#include <math.h>
//int main()
//{
//	double r = 16;
//	double m = sqrt(r);
//	printf("%lf\n", m);
//	return 0;
//}

//int Add(int x, int y);
//int main()
//{
//	int a = 0;
//	int b = 0;
//	scanf("%d %d", &a, &b);
//	int c = Add(a, b);
//	printf("sum=%d", c);
//	return 0;
//}
//int Add(int x, int y)
//{
//	int z = 0;
//	z = x + y;
//	return z;
//}



//void set_arr(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		arr[i] = -1;
//	}
//}
//void print_arr(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//}
//
//int main()
//{
//	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	set_arr(arr,sz);//设置数组内容为 - 1
//	print_arr(arr,sz);//打印数组内容
//	return 0;
//}




//函数递归
//求第n个斐波那契数
//1 1 2 3 5 8 13 21 34 55......
//第一个数：1
//第二个数：1+0=1
//第三个数：1+1=2
//第四个数：2+1=3
//第五个数：3+2=5
//第六个数：5+3=8
//第七个数：8+5=13
//第八个数：13+8=21
//第九个数：21+13=34
//第十个数：34+21=55
//...
//第n个数：（n-1）+(n-2)=n

//int Fib(int n)
//{
//	if (n <= 2)
//		return 1;
//	else
//		return Fib(n - 1) + Fib(n - 2);
//}
//
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int r = Fib(n);
//	printf("%d\n", r);
//	return 0;
//}
//但是上面的代码，会出问题，输入50时，运行结果慢且是错误结果
//因为50—> 49    +    48   49->48+47  48->47+46  
//          |            |
//         48+47      47+46
//         |   |      |   |
//   47+46  46+45  46+45  45+44
// ......
//我们会发现出现大量数据重复运算，如：count=39088169,意思是把第3个斐波那契数重复计算39088169次
//int count = 0;
//int Fib(int n)
//{
//	if (n == 3)
//		count++;
//	if (n <= 2)
//		return 1;
//	else
//		return Fib(n - 1) + Fib(n - 2);
//}
//
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int r = Fib(n);
//	printf("%d\n", r);
//	printf("count=%d\n", count);
//	return 0;
//}
//因此，使用递归方法并不是适用于全部代码中，所以不要过于迷恋递归方法
//下面不使用递归方法，用循环方法
//设a=1,b=1,c=a+b
//原来是第一个数为a，第二个数为b：现在把第二个数变成a,第三个数相当于把c换成b，第四个数就是c=a+b，依此类推

//int Fib(int n)
//{
//	int a = 1;
//	int b = 1;
//	int c = 0;
//	if (n <= 2)
//		return 1;
//	while (n > 2)
//	{
//		c = a + b;
//		a = b;
//		b = c;
//		n--;
//	}
//	return c;
//}
//
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int r = Fib(n);
//	printf("%d\n", r);
//	return 0;
//}
//会出数字大结果错的现象，是因为数字结果太大了

//青蛙跳台阶问题
//一只青蛙，一次可以跳1个台阶，也可以跳两个台阶，问，这只青蛙，跳到第n个台阶，有多少种跳法
//最后一次跳台阶，有两种跳法；跳到第n个台阶时，在之前有n-1个台阶所以有n-1个跳法，在从n-1个台阶时，有n-2个台阶，则有n-2个跳法
//所以n=(n-1)+(n-2)个跳法，但第一个台阶有一种跳法，第二个台阶有二种跳法

//看比特大博哥


//操作符
//
//int main()
//{
//	printf("%d\n", 15);
//	printf("%d\n", 0xF);//十六进制
//	printf("%d\n", 017);//八进制
//	return 0;
//}

//int fun()
//{
//	static int count = -1;
//	//static可以使count在这里里面累积数值继续计算
//	return ++count;
//}
//
//int main()
//{
//	int answer;
//	answer = fun() - fun() * fun();
//	//       4     -  2    *  3 = -2
//	//       2     -  3    *  4 = -10
//	//       3     -  2    *  4 = -5
//	//会出现几种不同的值，所以优先性，结合性要慎用
//	printf("%d\n", answer);
//	return 0;
//}

//int main()
//{
//	int i = 1;
//	int ret = (++i) + (++i) + (++i);
//	printf("%d\n", ret);//ret的值在不同编译器下是不一样的，在VS2019里面为12，在dec++里面为10
//	printf("%d\n", i);
//	return 0;
//}


//int main()
//{
//	int n = 20;
//	char ch = 't';
//	int* pn = &n;
//	char* pi = &ch;
//	//pn是指针变量，是用来存放地址的，地址=指针
//	//int说明pn指向的对象是int类型，*说明pn是指针变量
//    printf("%d\n", *pn);
//	printf("%c\n", *pi);
//	return 0;
//}
//* --解引用操作符- 间接访问操作符

//注意指针变量的⼤⼩和类型是⽆关的，只要指针类型的变量，在相同的平台下，⼤⼩都是相同的。
//int main()
//{
//	printf("%zd\n", sizeof(char*));
//	printf("%zd\n", sizeof(short*));
//	printf("%zd\n", sizeof(int*));
//	printf("%zd\n", sizeof(double*));
//
//	return 0;
//}

//指针类型决定在对指针进行解引用操作的时候，访问几个字节
//char*--解引用访问1个字节
//int*--解引用访问4个字节
//short*--解引用访问2个字节

//int main()
//{
//	int n = 0x11223344;
//	int* pi = &n;
//	char* pc = &n;
//	printf("&n  =%p\n", &n);
//	printf("pi  =%p\n", pi);
//	printf("pi+1=%p\n", pi+1);
//	printf("pc  =%p\n", pc);
//	printf("pc+1=%p\n", pc+1);
//	return 0;
//}

//void* 是无具体类型的指针,可以接收不同类型的地址，但是无法直接进行指针运算
//int main()
//{
//	int n = 10;
//	void* pv = &n;//当我们想强制性把int转换成char，就可以写成void*
//	*(int*)pv = 200;
//	printf("%d\n", n);
//
//	//不可以写成：
//	//*pv=20;
//	return 0;
//}

//const修饰指针
//int const * p;//const 放在*的左边做修饰,如：

int main()
{
	//int num = 100;
	//int * p = &num;
	//*p = 20;
	//printf("%d\n", num);//可以改

	//加const *
	//int a = 10;
	//int num = 100;
	//int const* p = &num;
	////*p = 20;//因为有const，把值固定了，不能通过*p=20，这种赋值方式改变
	//printf("%d\n", num);

	//加*  const
	//int a = 10;
	//int num = 100;
	//int* const p = &num;
	////*p = 20;//可以改变值
	////p = &a;//不可以改变
	//printf("%d\n", num);

	//两边都加const  int const *const p
	//int num = 100;
	//int const* const p = &num;
	//*p=20;
	//p=&a;
	//这两个都不可以改
	//printf("%d\n", &num);
	return 0;
}

